package com.example.websocket.handler;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Hashtable;
import java.util.Map;

import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.alibaba.fastjson.JSON;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.AppendObjectRequest;
import com.aliyun.oss.model.AppendObjectResult;
import com.aliyun.oss.model.ObjectMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * @author LiYuhang
 * @version 0.1
 * @date 2023/9/20 15:10
 */
@ServerEndpoint("/audio-upload")
@Component
public class AudioUploadHandler extends TextWebSocketHandler {

    private static final Logger log = LoggerFactory.getLogger(AudioUploadHandler.class);
    private static final String ACCESS_KEY_ID = "LTAI5t9UfFWv9hWSXCNT8vh8";
    private static final String ACCESS_KEY_SECRET = "IgA5fBGVg8Ajw7y9vb7G7lZVYQct9g";
    private static final String ENDPOINT = "oss-cn-shanghai.aliyuncs.com";
    private static final String BUCKET_NAME = "sto-station-digital-twin-test";

    private File audioFile;
    private FileOutputStream outputStream;
    private OSS ossClient;
    private String uploader = "liyuhang";
    private String uploadTime;

    private static final Map<String, Session> connections = new Hashtable<>();
    private static ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    public static Long length = 0L;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        audioFile = File.createTempFile("audio", ".wav");
        outputStream = new FileOutputStream(audioFile);

        ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

        log.info("sessionInfo:{}", JSON.toJSONString(session.getAttributes()));
        //// 获取上传人信息
        // 获取上传时间
        uploadTime = LocalDateTimeUtil.format(LocalDateTimeUtil.now(), DatePattern.PURE_DATE_FORMATTER);

        session.sendMessage(new TextMessage("Connection established. Start uploading audio."));
    }

    @Override
    @OnMessage
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        log.info("handleMessage:{}", JSON.toJSONString(message));
        if (message instanceof BinaryMessage) {
            BinaryMessage binaryMessage = (BinaryMessage)message;
            byte[] audioData = binaryMessage.getPayload().array();
            outputStream.write(audioData);
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        outputStream.close();

        ObjectMetadata meta = new ObjectMetadata();
        //             // 指定上传的内容类型。
        meta.setContentType("text/plain");

        AppendObjectRequest request = new AppendObjectRequest(BUCKET_NAME, generateFileName(), audioFile,meta);
        request.setPosition(length);
        final AppendObjectResult objectResult = ossClient.appendObject(request);

        audioFile.delete();
        length = objectResult.getNextPosition();
        ossClient.shutdown();
        log.info("文件上传成功");
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        exception.printStackTrace();
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    private String generateFileName() {
        String fileName = "wb_demo/" + uploader + "_" + uploadTime + ".wav";
        // // 替换时间中的冒号，以避免在文件名中引起问题
        return fileName.replace(":", "-");
    }
}
